package com.hucais.etl.common.dao;

import cn.hutool.core.lang.Pair;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import com.hucais.core.utils.DefaultPropertiesUtil;
import com.hucais.etl.common.bean.CandidateCategory;
import com.hucais.etl.common.bean.DDCategory;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class MysqlDao {
    private static final Logger LOG = LoggerFactory.getLogger(MysqlDao.class);

    /**
     * 获取大学高校数据Map
     *
     * @return
     */
    public static Map<String, List<String>> getUniversityMap() {
        Map<String, List<String>> map = new HashMap<>();

        try {
            List<Entity> all = Db.use().findAll(DefaultPropertiesUtil.get("dim.university"));
            for (Entity e : all) {
                String type = e.getStr("type");
                String name = e.getStr("name");
                List<String> list = null;
                if (map.containsKey(type)) {
                    list = map.get(type);
                    list.add(name);
                } else {
                    list = new ArrayList<>();
                    list.add(name);
                }
                map.put(type, list);
            }
        } catch (Exception e) {
            LOG.error("获取大学高校数据映射出错", e);
        }
        return map;
    }

    /**
     * 获取出版社选品Map
     *
     * @return
     */
    public static Map<String, Long> getPublishingHouseMap() {
        try {
            List<Entity> list = Db.use().findAll(DefaultPropertiesUtil.get("dim.publishing_house"));
            return list.parallelStream()
                    .filter(e -> StringUtils.isNotBlank(e.getStr("name")))
                    .map(e -> new Pair<>(e.getStr("name"), e.getLong("sales")))
                    .collect(Collectors.toMap(Pair::getKey, Pair::getValue));
        } catch (Exception e) {
            LOG.error("获取出版社选品映射出错", e);
            return null;
        }
    }


    /**
     * 获取候选分类名单列表
     *
     * @return
     */
    public static List<CandidateCategory> getCandidateCategoryList() {
        try {
            List<Entity> list = Db.use().findAll(DefaultPropertiesUtil.get("candidate.category.table"));
            return list.stream()
                    .filter(e -> StringUtils.isNotBlank(e.getStr("keywords")))
                    .map(e -> {
                        CandidateCategory c = new CandidateCategory();
                        c.setCategoryName(e.getStr("category_name"));

                        String[] split = e.getStr("keywords").split(",");
                        c.setKeywordList(Arrays.asList(split));
                        return c;
                    }).collect(Collectors.toList());
        } catch (Exception e) {
            LOG.error("获取候选分类名单列表出错", e);
            return null;
        }
    }

    /**
     * 获取二级分类为Key的分类Map
     *
     * @return
     */
    public static Map<String, DDCategory> getSecondCategoryToKeyMap() {
        try {
            List<Entity> list = Db.use().findAll(DefaultPropertiesUtil.get("dim.dd.category.table"));
            List<DDCategory> collect = list.parallelStream()
                    .map(e -> {
                        DDCategory d = new DDCategory();
                        d.setFirstCategory(e.getStr("first_category"));
                        d.setSecondCategory(e.getStr("second_category"));
                        d.setThirdCategory(e.getStr("third_category"));
                        d.setFourthCategory(StringUtils.defaultIfBlank(e.getStr("fourth_category"), StringUtils.EMPTY));
                        return d;
                    }).collect(Collectors.toList());

            return collect.parallelStream().collect(Collectors.toMap(DDCategory::getSecondCategory, Function.identity(), (entity1, entity2) -> entity1));
        } catch (Exception e) {
            LOG.error("获取二级分类为Key的分类Map出错", e);
            return null;
        }
    }

    /**
     * 获取各分类权重Map
     *
     * @return
     */
    public static Map<String, DDCategory> getCategoryWeightMap() {
        try {
            List<Entity> list = Db.use().findAll(DefaultPropertiesUtil.get("dim.dd.category.table"));
            List<DDCategory> collect = list.parallelStream()
                    .map(e -> {
                        DDCategory d = new DDCategory();
                        Double yearSalesWeight = BigDecimal.valueOf(e.getDouble("year_sales_weight")).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).doubleValue();
                        Double authorPopularityWeight = BigDecimal.valueOf(e.getDouble("author_popularity_weight")).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).doubleValue();
                        Double doubanScoreWeight = BigDecimal.valueOf(e.getDouble("douban_score_weight")).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).doubleValue();
                        Double publishingHouseWeight = BigDecimal.valueOf(e.getDouble("publishing_house_weight")).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).doubleValue();

                        d.setFirstCategory(e.getStr("first_category"));
                        d.setSecondCategory(e.getStr("second_category"));
                        d.setThirdCategory(e.getStr("third_category"));
                        d.setFourthCategory(StringUtils.defaultIfBlank(e.getStr("fourth_category"), StringUtils.EMPTY));
                        d.setYear_sales_weight(yearSalesWeight);
                        d.setAuthor_popularity_weight(authorPopularityWeight);
                        d.setDouban_score_weight(doubanScoreWeight);
                        d.setPublishing_house_weight(publishingHouseWeight);
                        d.setBrand_plus(e.getDouble("brand_plus"));
                        return d;
                    }).collect(Collectors.toList());

            Map<String, DDCategory> map = new HashMap<>();
            for (DDCategory d : collect) {
                String firstCategory = d.getFirstCategory();
                String secondCategory = d.getSecondCategory();
                String key = firstCategory + "_" + secondCategory;
                if (!map.containsKey(key)) {
                    map.put(key, d);
                }
            }
            return map;
        } catch (Exception e) {
            LOG.error("获取当当-多层分类数据出错", e);
            return null;
        }
    }

    /**
     * 获取当当-历史多层分类数据
     *
     * @return
     */
    public static Map<String, DDCategory> getDDHistoryCategoryMap() {
        try {
            List<Entity> list = Db.use().findAll(DefaultPropertiesUtil.get("dim.dd.history.category.table"));
            List<DDCategory> collect = list.parallelStream()
                    .map(e -> {
                        DDCategory d = new DDCategory();
                        Double yearSalesWeight = BigDecimal.valueOf(e.getDouble("year_sales_weight")).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).doubleValue();
                        Double authorPopularityWeight = BigDecimal.valueOf(e.getDouble("author_popularity_weight")).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).doubleValue();
                        Double doubanScoreWeight = BigDecimal.valueOf(e.getDouble("douban_score_weight")).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).doubleValue();
                        Double publishingHouseWeight = BigDecimal.valueOf(e.getDouble("publishing_house_weight")).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).doubleValue();

                        d.setHistoryCategory(e.getStr("history_category"));
                        d.setFirstCategory(e.getStr("first_category"));
                        d.setSecondCategory(e.getStr("second_category"));
                        d.setThirdCategory(e.getStr("third_category"));
                        d.setFourthCategory(StringUtils.defaultIfBlank(e.getStr("fourth_category"), StringUtils.EMPTY));
                        d.setYear_sales_weight(yearSalesWeight);
                        d.setAuthor_popularity_weight(authorPopularityWeight);
                        d.setDouban_score_weight(doubanScoreWeight);
                        d.setPublishing_house_weight(publishingHouseWeight);
                        d.setBrand_plus(e.getDouble("brand_plus"));
                        return d;
                    }).collect(Collectors.toList());

            return collect.parallelStream().collect(Collectors.toMap(DDCategory::getHistoryCategory, Function.identity(), (entity1, entity2) -> entity1));
        } catch (Exception e) {
            LOG.error("获取当当-历史分类数据出错", e);
            return null;
        }
    }
}
